package com.xgc.erp.order.sell.ctrl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.jfinal.aop.Inject;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.xgc.common.base.BaseController;
import com.xgc.common.config.Constan;
import com.xgc.common.kit.ExcelKit;
import com.xgc.common.model.*;
import com.xgc.common.util.ChineseNumber;
import com.xgc.common.visit.Visitor;
import com.xgc.common.vo.Feedback;
import com.xgc.common.vo.Grid;
import com.xgc.erp.info.customer.service.CustomerService;
import com.xgc.erp.order.sell.service.IncomeDetailService;
import com.xgc.erp.order.sell.service.SellDetailService;
import com.xgc.erp.order.sell.service.SellOrderService;
import com.xgc.portal.core.service.SysUserService;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

//@ControllerBind(path = "/erp/order/sell")
public class SellController extends BaseController {
    @Inject
    SellOrderService service;
    @Inject
    SellDetailService detailService;
    @Inject
    CustomerService customerService;
    @Inject
    SysUserService sysUserService;
    @Inject
    IncomeDetailService incomeDetailService;

    public void index() {
        setAttr("originatorList", service.queryUserIdAndNameRecord());
        render("index.html");
    }

    public void getInfo(){
        String orderId = get("orderId");
        SellOrder sellOrder = (SellOrder) service.findById(orderId);
        renderJson(sellOrder);
    }

    /**
     * 表格数据
     */
    public void list(){
        int pageNum = getParaToInt("pageNumber",1);
        int pageSize = getParaToInt("pageSize",10);
        String userName = get("userName",null);// 开单人
        Date startTime = getDate("startTime",null);
        Date endTime = getDate("entTime", null);
        String customerName = get("customerName",null);// 开单人
        String status = get("status",null);
        List<Object> params = new ArrayList<>();
        String sql = Db.getSql("erp.getSellList");
        if(userName != null && !userName.equals("")){
            params.add(userName);
            sql += " and t3.user_code = ?";
        }
        if(customerName != null && !customerName.equals("")){
            params.add("%"+customerName+"%");
            sql += " and t2.customer_name like ?";
        }
        if(startTime != null){
            params.add(startTime);
            sql += " and originat_time >= ? ";
        }
        if(endTime != null){
            params.add(endTime);
            sql += " and originat_time <= ? ";
        }
        if(status != null && !status.equals("")){
            params.add(status);
            sql += " and status = ? ";
        }
        // 管理员和老板，查看全部客户
        String visitor = getVisitor().getCode();
        if(checkRole(visitor)){
            params.add(visitor);
            sql += " and t1.creator = ?";
        }
        // 查询总条数
        String countSql = "select count(1) totalRow from (" + sql + " ) count_table ";
        Integer totalRow = Db.queryInt(countSql,params.toArray());
        Grid grid = new Grid();
        grid.setTotalRow(totalRow);
        // 分页排序
        params.add((pageNum-1)*pageSize);
        params.add(pageSize);
        sql += " order by t1.create_time desc limit ?,? ";
        List<Record> queryList = Db.find(sql,params.toArray());
        renderJson(grid.setList(queryList));
//        renderJson(service.queryForList(sql,getParaToInt("pageNumber",1), getParaToInt("pageSize",10),record,"order by create_time desc"));
    }

    /**
     * 新增页面
     */
    public void add() {
        setAttr("orderStatusMap", Constan.ORDER_STATUS_MAP);
        setAttr("orderContainBillMap",Constan.ORDER_CONTAIN_BILL_MAP);
        setAttr("orderSettleWayMap",Constan.ORDER_SETTLE_WAY_MAP);
        setAttr("orderCarriageTypeMap",Constan.ORDER_CARRIAGE_TYPE_MAP);
        render("add.html");
    }

    public void save(){
        SellOrder order = getBean(SellOrder.class);
        order.setOrderId(service.getPrimaryKey(Constan.SEQ_SELL_ORDER));
        order.setCreator(getVisitor().getCode());
        order.setCreateTime(new Date());
        if(!service.save(order)){
            setException("数据插入失败");
        }
        render("add.html");
    }

    /**
     * 编辑页面
     */
    public void edit(){
        String orderId = get("orderId");
        Record record = new Record();
        record.set("order_id",orderId);
        SellOrder sellOrder = service.getSellOrderById(orderId);
        setAttr("sellOrder", sellOrder);
        setAttr("orderStatusMap", Constan.ORDER_STATUS_MAP);
        setAttr("orderContainBillMap",Constan.ORDER_CONTAIN_BILL_MAP);
        setAttr("orderSettleWayMap",Constan.ORDER_SETTLE_WAY_MAP);
        setAttr("orderCarriageTypeMap",Constan.ORDER_CARRIAGE_TYPE_MAP);
        render("edit.html");
    }

    public void update(){
        SellOrder order = getBean(SellOrder.class);
        order.setModifier(getVisitor().getCode());
        order.setUpdateTime(new Date());
        if(!service.update(order)){
            setException("数据插入失败");
        }
        render("edit.html");
    }

    /**
     * 采购单预览
     */
    public void review(){
        String orderId = get("orderId");
        SellOrder sellOrder = service.getSellOrderById(orderId);
        setAttr("sellOrder", sellOrder);
        setAttr("orderStatusMap", Constan.ORDER_STATUS_MAP);
        setAttr("orderContainBillMap",Constan.ORDER_CONTAIN_BILL_MAP);
        setAttr("orderSettleWayMap",Constan.ORDER_SETTLE_WAY_MAP);
        setAttr("orderCarriageTypeMap",Constan.ORDER_CARRIAGE_TYPE_MAP);
        render("review.html");
    }

    public void delete() {
        service.deleteByIds(getIds());
        renderJson(Feedback.success());
    }

    /**
     * 通过,支持批量操作
     */
    public void approve(){
        List<String> ids = getIds();
        List<Integer> idList = new ArrayList<>();
        for(String id:ids){
            idList.add(Integer.parseInt(id));
        }
        Visitor vs = getVisitor();
        service.modifyStatus(idList,Constan.STATUS_1002,vs.getCode());
        renderJson(Feedback.success());
    }

    /**
     * 退回，支持批量操作
     */
    public void refuse(){
        List<String> ids = getIds();
        List<Integer> idList = new ArrayList<>();
        for(String id:ids){
            idList.add(Integer.parseInt(id));
        }
        Visitor vs = getVisitor();
        service.modifyStatus(idList,Constan.STATUS_1003,vs.getCode());
        renderJson(Feedback.success());
    }

    /**
     * 更新打印状态
     */
    public void updatePrintStatus(){
        String orderId = get("orderId");
        String status = Constan.SELL_ORDER_STATUS_1001;
        SellOrder sellOrder = (SellOrder) service.findById(orderId);
        sellOrder.setStatus(status);
        boolean flag = service.update(sellOrder);
        if(!flag){
            renderJson(Feedback.error("保存打印状态失败！"));
        }
        renderJson(Feedback.success());
    }

    public void printTemp(){
        String orderId = get("orderId","");
        SellOrder order = (SellOrder) service.findById(orderId);
        String carriageType = order.getCarriageType();
        Customer customer = (Customer) customerService.findById(order.getCustomerId().toString());
        List<Record> details = detailService.getList(orderId);
        for(int i=0;i<details.size();i++){ // 添加序号
            details.get(i).set("num",i+1);
            details.get(i).set("carriage",Constan.ORDER_CARRIAGE_TYPE_MAP.get(carriageType)); // 运费类型
        }
        String madeBy = sysUserService.findByUserCode(order.getOriginator()).getUserName();
        List<Record> incomeDetails = incomeDetailService.getList(orderId);
        String payType;
        String str = "（";
        if(incomeDetails !=null && incomeDetails.size() > 0){
            for(Record r:incomeDetails){
                payType = r.getStr("pay_type")+"、";
                str += payType;
            }
            str = str.substring(0, str.length()-1);// 去除最后一个 、号
        }else{
            str += "未支付";
        }
        str += "）";

        setAttr("company","深圳市鑫广驰科技有限公司");
        setAttr("address","地址：广东省佛山市里水镇流潮村流潮大道深圳市鑫广驰科技有限公司");
        setAttr("orderTitle","送货单");
        setAttr("madeBy",madeBy);
        SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
        String postTime = f.format(order.getPlanTime());
        setAttr("postTime",postTime);
        setAttr("customer",customer);
        setAttr("order",order);
        setAttr("details",details);
        setAttr("settleWay",Constan.ORDER_SETTLE_WAY_MAP.get(order.getSettleWay()) + str);
        setAttr("totalMoney",ChineseNumber.toChineseNumber(order.getTotalAmount()));
        render("sellOrderTemp.html");
    }

    public void saveOrder(){
        HttpServletRequest request = getRequest();
        Integer customerId = Integer.parseInt(get("customerId","0"));// 客户ID
        Date planTime = getDate("planTime",new Date());// 计划到货时间
        Date actualTime = getDate("actualTime",new Date());// 实际到货时间
        String originator = get("originator","");// 开单人
        Date originatTime = getDate("originatTime",new Date());// 开单时间
        String settleWay = get("settleWay","0");//结算方式
        Double totalAmount = Double.parseDouble(get("totalAmount","0")); // 总金额
        String containBill = get("containBill","0");                // 是否含税
        Double taxRate = Double.parseDouble(get("taxRate","0"));    // 税率
        String logisticsNum = get("logisticsNum",""); // 物流编号
        String carriageType = get("carriageType","");// 运费类型
        Double carriage = Double.parseDouble(get("carriage","0")); // 运费
        Double realCarriage = Double.parseDouble(get("realCarriage","0"));// 实际运费
        String status = Constan.SELL_ORDER_STATUS_1000;// 未打印状态
        String creator = getVisitor().getCode();
        Date createTime = new Date();

        SellOrder sellOrder = new SellOrder();
        sellOrder.setOrderId(service.getPrimaryKey(Constan.SEQ_PURCHASE_ORDER))
                .setCustomerId(customerId).setOriginator(originator).setSettleWay(settleWay)
                .setTotalAmount(totalAmount).setContainBill(containBill).setTaxRate(taxRate)
                .setLogisticsNum(logisticsNum).setCarriage(carriage).setStatus(status)
                .setOriginatTime(originatTime).setPlanTime(planTime).setActualTime(actualTime)
                .setCreateTime(createTime).setCreator(creator).setCarriageType(carriageType).setRealCarriage(realCarriage);

        // 获取订单项信息
        String jsonStr = request.getParameter("detailList");
        JSONArray res = JSON.parseArray(jsonStr);
        List<SellDetail> details = res.toJavaList(SellDetail.class);

        // 支付列表
        String json = request.getParameter("payList");
        res = JSON.parseArray(json);
        List<IncomeDetail> incomeDetails = res.toJavaList(IncomeDetail.class);

        // 事务处理
        boolean flag = Db.tx( () -> {
            if(!sellOrder.save()) return false;
            for (SellDetail detail:details){
                detail.setDetailId(service.getPrimaryKey(Constan.SEQ_PURCHASE_DETAIL))
                        .setOrderId(sellOrder.getOrderId())
                        .setCreateTime(createTime).setCreator(creator);
                if(!detail.save())  return false;
            }
            for(IncomeDetail detail:incomeDetails){
                detail.setDetailId(service.getPrimaryKey(Constan.SEQ_OUTCOME_DETAIL))
                        .setOrderId(sellOrder.getOrderId()).setStatus("1000")
                        .setCreateTime(createTime).setCreator(creator).setTransTime(createTime);
                if(!detail.save()) return false;
            }
            return true;
        });

        renderJson(Feedback.success());
    }

    public void updateOrder(){
        HttpServletRequest request = getRequest();
        String orderId = get("orderId");
        Integer customerId = Integer.parseInt(get("customerId","0"));// 客户ID
        Date planTime = getDate("planTime",new Date());// 计划到货时间
        Date actualTime = getDate("actualTime",new Date());// 实际到货时间
        String originator = get("originator","");// 开单人
        Date originatTime = getDate("originatTime",new Date());// 开单时间
        String settleWay = get("settleWay","0");//结算方式
        Double totalAmount = Double.parseDouble(get("totalAmount","0")); // 总金额
        String containBill = get("containBill","0");                // 是否含税
        Double taxRate = Double.parseDouble(get("taxRate","0"));    // 税率
        String logisticsNum = get("logisticsNum",""); // 物流编号
        String carriageType = get("carriageType","");// 运费类型
        Double carriage = Double.parseDouble(get("carriage","0")); // 运费
        Double realCarriage = Double.parseDouble(get("realCarriage","0"));// 实际运费
        String status = Constan.SELL_ORDER_STATUS_1000;// 未打印状态
        String modifier = getVisitor().getCode();
        Date updateTime = new Date();

        SellOrder sellOrder = new SellOrder();
        sellOrder.setOrderId(Integer.parseInt(orderId))
                .setCustomerId(customerId).setOriginator(originator).setSettleWay(settleWay)
                .setTotalAmount(totalAmount).setContainBill(containBill).setTaxRate(taxRate)
                .setLogisticsNum(logisticsNum).setCarriage(carriage).setStatus(status)
                .setOriginatTime(originatTime).setPlanTime(planTime).setActualTime(actualTime)
                .setUpdateTime(updateTime).setModifier(modifier).setCarriageType(carriageType).setRealCarriage(realCarriage);

        // 获取订单项信息
        String jsonStr = request.getParameter("detailList");
        JSONArray res = JSON.parseArray(jsonStr);
        List<SellDetail> details = res.toJavaList(SellDetail.class);

        // 支付列表
        String json = request.getParameter("payList");
        res = JSON.parseArray(json);
        List<IncomeDetail> incomeDetails = res.toJavaList(IncomeDetail.class);

        // 事务处理:sell_order 表插入，sell_detail 表删除数据，再插入 , income_detail 表删除数据再插入
        boolean flag = Db.tx( () -> {
            if(!sellOrder.update()) return false;
            // 先删除
            List<Record> detailList = detailService.getList(orderId);
            if(detailList!=null && detailList.size()>0){
                for(Record detail : detailList){
                    detailService.deleteById(detail.get("detail_id").toString());
                }
            }
            // 再插入
            for (SellDetail detail:details){
                detail.setDetailId(service.getPrimaryKey(Constan.SEQ_PURCHASE_DETAIL))
                        .setOrderId(sellOrder.getOrderId())
                        .setCreateTime(updateTime).setCreator(modifier);
                if(!detail.save())  return false;
            }
            // 先删除
            List<Record> detailList1 = incomeDetailService.getList(orderId);
            if(detailList1 != null&& detailList1.size()>0){
                for(Record detail : detailList1){
                    incomeDetailService.deleteById(detail.get("detail_id").toString());
                }
            }
            // 再插入
            for(IncomeDetail detail:incomeDetails){
                detail.setDetailId(service.getPrimaryKey(Constan.SEQ_OUTCOME_DETAIL))
                        .setOrderId(sellOrder.getOrderId()).setStatus("1000")
                        .setCreateTime(updateTime).setCreator(modifier).setTransTime(updateTime);
                if(!detail.save()) return false;
            }
            return true;
        });

        renderJson(Feedback.success());
    }

    /**
     * 导出excel:日期、产品名称、单位、数量、单价、运费类别、总价、收款账号、客户地址、底价、运费、总价、利润、备注
     * @throws IOException
     */
    public void export() throws IOException {
        String userName = get("userName",null);// 开单人
        Date startTime = getDate("startTime",null);
        Date endTime = getDate("entTime", null);
        String status = get("status",null);
        String customerName = get("customerName",null);
        List<Object> params = new ArrayList<>();
        String sql = Db.getSql("erp.exportSellOrderDetail");
        if(userName != null && !userName.equals("")){
            params.add(userName);
            sql += " and t5.user_code = ?";
        }
        if(customerName != null && !customerName.equals("")){
            params.add("%"+customerName+"%");
            sql += " and t4.customer_name like ?";
        }
        if(startTime != null){
            params.add(startTime);
            sql += " and t2.originat_time >= ? ";
        }
        if(endTime != null){
            params.add(endTime);
            sql += " and t2.originat_time <= ? ";
        }
        if(status != null && !status.equals("")){
            params.add(status);
            sql += " and t2.status = ? ";
        }
        String visitor = getVisitor().getCode();
        if(checkRole(visitor)){
            params.add(visitor);
            sql += " and t2.creator = ?";
        }
        List<Record> sellOrderList = Db.find(sql,params.toArray());// 数据准备
        // 表格导出
        String[] title = new String[]{"日期","产品名称","单位","数量","单价","运费类别","总价","收款账号","客户地址","底价","运费","总价","利润","备注"};
        String fileName = visitor+"-销售单";
        ExcelKit.exportExcelxlsx(getResponse(),title,fileName,sellOrderList);
    }

    private boolean checkRole(String visitor){
        // 管理员和老板，查看全部客户
        String role_sql = "select * from sys_user_role where role_code in ('boss','admin')";
        List<Record> roleList = Db.find(role_sql);
        int count = 0;
        for(Record r:roleList){
            if(visitor.equals(r.getStr("user_code"))){
                count ++;
            }
        }
        return count == 0;
    }


}
